import {SimpleDateFormat} from "../utils/SimpleDateFormat";
import Beans from "../utils/Beans";
import Logger from "../utils/Logger";
import ChatsContentStore, {ChatsStore} from "../model/store/ChatsContentStore";
import {UserInfoStore} from "../model/store/UserInfoStore";

var sdk = require('../utils/echatim-sdk.js');
var EChatIMApis = sdk.apis;


export default class ShareStore {
    // windows 窗口 (chat:聊天, system:系统消息)
    windowTab =  '';
    online = 0;
    avatarType = ''; // 修改头像的类型 (self:自己的头像; room = 讨论组的头像)
    sessionTopList = ['添加好友','添加讨论组', '系统消息']; // 放置在会话列表的功能列表
    sessionList = []; // 会话列表 Array<HistorySessionStore>
    friendList = []; // 好友列表 Array<FriendListStore>
    roomList = []; // 讨论组列表 Array<RoomListStore>
    friendToAddRoomList = []; // 待添加到讨论组的朋友列表 Array<FriendToAddRoomStore>
    // listExtraInfo = {}; // 会话列表, 好友列表, 讨论组列表 的补充信息
    faces = []; // 表情gif
    // 系统消息
    systemMessages = [];
    // 用户信息
    userInfo = new UserInfoStore(); // 用户信息 UserInfoStore
    // 聊天正文
    chatsContent = new ChatsContentStore(); // 聊天正文 ChatsContentStore

    showToast(msg){
        // Toast.show(msg, Toast.LONG);
        wx.showToast({title: msg});
    }
    showApiErrorToast(e) {
        console.trace(e);
        if (e instanceof Error) {
            this.showToast(e+'');
        } else if (e.errorMessage !== undefined) {
            this.showToast(e.errorMessage);
        }
    }

    isSelectPersonTag(){
        return this.chatsContent.select === 'friend' || this.chatsContent.select === 'session';
    };
    // data: CommonListData
    selectChartContent(category, data, roomOwner){
        this.windowTab = 'chat';
        this.chatsContent.select = category;
        this.chatsContent.selectId = data.id;
        this.chatsContent.friendInfo.auid = data.id;
        this.chatsContent.friendInfo.name = data.name;
        this.chatsContent.friendInfo.avatar = data.avatar;

        if (category === 'session') {
            this.chatsContent.select = 'session';
            this.chatsContent.selectId = data.id;
            this.chatsContent.friendInfo.auid = data.id;
            this.chatsContent.friendInfo.name = data.name;
            this.chatsContent.friendInfo.avatar = data.avatar;
        } else if (category === 'friend') {
            this.chatsContent.select = 'friend';
            this.chatsContent.selectId = data.id;
            this.chatsContent.friendInfo.auid = data.id;
            this.chatsContent.friendInfo.name = data.name;
            this.chatsContent.friendInfo.avatar = data.avatar;
            this.chatsContent.friendInfo.online = data.online;
        } else if (category === 'room') {
            this.chatsContent.select = 'room';
            this.chatsContent.selectId = data.id;
            this.chatsContent.roomInfo.rid = parseInt(data.id);
            this.chatsContent.roomInfo.name = data.name;
            this.chatsContent.roomInfo.avatar = data.avatar;
            if(roomOwner){
                this.chatsContent.roomInfo.owner = roomOwner;
            }
        }

        this.cleanUnReadMessage(category, this.chatsContent.selectId); // 清空消息未读数
    }

    cleanUnReadMessage(listType, key) {
        if(listType === 'session'){
            const target = globalStore.sessionList.filter(function (v) {
                return v.toTarget === key;
            });
            if(target.length > 0){
                target[0].unread = 0;
            }
            // notify data list
            globalStore.notifySessionUpdate();
        }
        else if(listType === 'room'){
            const target = globalStore.roomList.filter(function (v) {
                return v.rid === parseInt(key);
            });
            if(target.length > 0){
                target[0].unread = 0;
            }
            // notify data list
            // globalStore.notifyRoomUpdate();
        }
        // notify data list

    }
    incrementUnReadMessage(listType, key) {
        if(listType === 'session'){
            const target = globalStore.sessionList.filter(function (v) {
                return v.toTarget === key;
            });
            if(target.length > 0){
                target[0].unread += 1;
            }
            // notify data list
            globalStore.notifySessionUpdate();
        }
        else if(listType === 'room'){
            const target = globalStore.roomList.filter(function (v) {
                return v.rid === parseInt(key);
            });
            if(target.length > 0){
                target[0].unread = target[0].unread === undefined ? 1 : target[0].unread + 1;
            }
            // notify data list
            globalStore.notifyRoomUpdate();
        }

    }

    // IEChatIMSDKListener
    sdkListener = {
        onConnected:()=> {
            globalStore.online = 1;
        },
        onDisConnected: ()=> {
            globalStore.online = 0;
        },
        // userInfo: UserListDTO
        onUserInfo:(userInfo)=> {
            globalStore.userInfo = userInfo;
        },
        // message: MessageReceiveDTO
        onMessageReceive:(message)=> {
            if (message.way === 'P2P' || message.way === 'P2R') {
                if(message.way === 'P2P'){
                    globalStore.incrementUnReadMessage('session', message.fromUser); // 最近会话消息未读数+1
                }
                else if(message.way === 'P2R'){
                    globalStore.incrementUnReadMessage('room', message.toTarget); // 群消息未读数+1
                }
                if (globalStore.windowTab === 'chat') {
                    // 群: 不要显示自己发送的消息
                    if (message.fromUser === globalStore.userInfo.auid) {
                        return;
                    }
                    // 收到'P2P', 但打开了其它窗口
                    if (message.way === 'P2P') {
                        if (!globalStore.isSelectPersonTag() || globalStore.chatsContent.selectId !== message.fromUser)
                            return;
                    }
                    // 收到'P2R', 但打开了其它窗口
                    if (message.way === 'P2R') {
                        if (globalStore.isSelectPersonTag() || parseInt(globalStore.chatsContent.selectId) !== parseInt(message.toTarget))
                            return;
                        //  群最后一条消息的时间为当前时间
                        const targetRoom = globalStore.roomList.filter(function (v) {
                            return v.rid === parseInt(message.toTarget);
                        });
                        if(targetRoom.length > 0){
                            targetRoom[0].lastMsgTime = SimpleDateFormat.format(new Date(), 'yyyy-MM-dd hh:mm:ss');
                        }
                    }
                    // 加入刚刚收到的信息到聊天窗口
                    const chat = new ChatsStore();
                    chat.toMe = 1;
                    chat.body = message.body;
                    chat.createTime = new Date();
                    globalStore.chatsContent.chats.push(chat);

                    // send Broadcast
                    // this.scrollMessageContainerToBottom();
                }
            }
        },
        onEventReceive:(event)=> {
            console.log("onEventReceive:" + Beans.json(event));
            if(event.eventType === 'CLIENT_ONLINE'){
                const jsonBody = Beans.bean(event.body);
                globalStore.sessionList.forEach(function (v) {
                    if(v.toTarget === jsonBody.auid){
                        v.online = jsonBody.online;
                    }
                });
                globalStore.friendList.forEach(function (v) {
                    if(v.auid === jsonBody.auid){
                        v.online = jsonBody.online;
                    }
                });
                if(globalStore.chatsContent.friendInfo.auid === jsonBody.auid){
                    globalStore.chatsContent.friendInfo.online = jsonBody.online;
                }

                globalStore.notifyFriendUpdate();
            }
        },
        // resp: Array<HistorySessionDTO>
        onSessionList:(resp)=> {
            globalStore.sessionList = resp.map((v)=>Beans.to(v));
            const targetAuids = globalStore.sessionList.map(function (v) {
                return v.toTarget;
            });
            globalStore.notifySessionUpdate();
            // 监听最近会话的在线状态
            EChatIMApis.addOnlineMonitor.call({auid:globalStore.userInfo.auid, targetAuids:targetAuids}).then((resp) => {
                // app.showToast("设置成功");
            }).catch((e) => {
                globalStore.showApiErrorToast(e);
                Logger.trace(e);
                // TODO: send broadcast
            })
        },
        // resp: Array<UserFriendListDTO>
        onFriendList:(resp)=> {
            globalStore.friendList = resp.map((v)=>Beans.to(v));
            const targetAuids = globalStore.friendList.map(function (v) {
                return v.auid;
            });
            // 监听朋友的在线状态
            EChatIMApis.addOnlineMonitor.call({auid:globalStore.userInfo.auid, targetAuids:targetAuids}).then((resp) => {
                globalStore.showToast("设置在线监听成功");
            }).catch((e) => {
                globalStore.showApiErrorToast(e);
                Logger.trace(e);
                // TODO: send broadcast
            })
        },
        // list: Array<UserBlackForbidListDTO>
        onBlacklistForbidList:(list) => {

        },
        // resp: Array<RoomListDTO>
        onRoomList:(resp)=> {
            globalStore.roomList = resp.map((v)=>Beans.to(v));
        },
        onError:(e)=> {
            Logger.trace(e);
            globalStore.showApiErrorToast(e);
            // TODO: send broadcast
        }

    };



    //  ---------- components 监听/广播 ------------//
    sessionListener = []; // Array<sessionListenerType>
    notifySessionUpdate(){
        this.sessionListener.forEach((listener)=>{
            listener(this.sessionList);
        })
    }
    // listener:sessionListenerType
    addSessionListener(listener){
        this.sessionListener.push(listener);
    }
    requestSessionUpdate(){
        const historyListSessionForm = {};  // new HistoryListSessionForm()
        historyListSessionForm.auid = this.userInfo.auid;
        historyListSessionForm.startTimestamp = 0;
        historyListSessionForm.endTimestamp = new Date().getTime();
        EChatIMApis.historyListSession.call(historyListSessionForm).then((response)=>{
            const sessions = response.data; // response.data as Array<HistorySessionStore>
            const preSessionMapByTarget = Beans.toMapByKey(this.sessionList, 'toTarget');
            this.sessionList = sessions.map((v)=>Beans.replace( preSessionMapByTarget.hasOwnProperty(v.toTarget) ? preSessionMapByTarget[v.toTarget] : {}, v));
            this.notifySessionUpdate();
        }).catch((e)=>{
            Logger.trace(e);
        })
    }

    // friendListener:Array<friendListenerType>
    friendListener = [];
    notifyFriendUpdate(){
        this.friendListener.forEach((listener)=>{
            listener(this.friendList);
        })
    }
    // listener:friendListenerType
    addFriendListener(listener){
        this.friendListener.push(listener);
    }
    requestFriendUpdate(){
        const userFriendListForm = {}; // new UserFriendListForm()
        userFriendListForm.auid = this.userInfo.auid;
        EChatIMApis.listFriends.call(userFriendListForm).then((response)=>{
            const friends = response.data; // response.data as Array<UserFriendListDTO>
            const preFriendMapByAuid = Beans.toMapByKey(this.friendList, 'auid');
            this.friendList = friends.map((v)=>Beans.replace( preFriendMapByAuid.hasOwnProperty(v.auid) ? preFriendMapByAuid[v.auid] : {}, v));
            this.notifyFriendUpdate();
        }).catch((e)=>{
            Logger.trace(e);
        })
    }

    // Array<roomListenerType>
    roomListener = [];
    notifyRoomUpdate(){
        this.roomListener.forEach((listener)=>{
            listener(this.roomList);
        })
    }
    // listener:roomListenerType
    addRoomListener(listener){
        this.roomListener.push(listener);
    }

    requestRoomUpdate(){
        const roomListJoinForm = {}; // new RoomListJoinForm()
        roomListJoinForm.auid = this.userInfo.auid;
        EChatIMApis.listRoomJoin.call(roomListJoinForm).then((response)=>{
            const rooms = response.data; // response.data as Array<RoomListDTO>
            const preRoomMapByRid = Beans.toMapByKey(this.roomList, 'rid');
            this.roomList = rooms.map((v)=>Beans.replace(preRoomMapByRid.hasOwnProperty(v.rid) ? preRoomMapByRid[v.rid] : {}, v));
            this.notifyRoomUpdate();
        }).catch((e)=>{
            Logger.trace(e);
        })
    }


    // Array<chatListenerType>
    chatListener = [];
    notifyChatUpdate(){
        this.chatListener.forEach((listener)=>{
            listener(this.chatsContent.chats);
        })
    }
    // listener:chatListenerType
    addChatListener(listener){
        this.chatListener.push(listener);
    }

}

export const globalStore = new ShareStore();


